package com.tcleaner;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
import com.tcleaner.table.CleanService;
import com.tcleaner.table.Config;
import org.apache.commons.cli.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.Map;
import java.util.Scanner;

public class Main {

    public static final String AppName = "table-cleaner";

    static {
        LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
        JoranConfigurator configurator = new JoranConfigurator();
        configurator.setContext(lc);
        lc.reset();
        String logBackConfig = System.getProperty("log_back_config");
        if (logBackConfig == null || logBackConfig.trim().length() == 0) {
            System.out.println("Exception: can not find log config.");
            System.exit(1);
        }
        try {
            configurator.doConfigure(new File(logBackConfig));
        } catch (JoranException e) {
            System.out.println("Exception: " + e.getMessage());
            System.exit(1);
        }
    }

    public static void main(String[] args) {
        PosixParser parser = new PosixParser();
        HelpFormatter hf = new HelpFormatter();
        hf.setWidth(110);

        Logger logger = LoggerFactory.getLogger(AppName);

        Options options = createOptions();
        try {
            CommandLine commandLine = parser.parse(options, args);
            if (commandLine.hasOption('h')) {
                hf.printHelp(AppName, options, true);
                System.exit(0);
            } else if (commandLine.hasOption('c')) {
                try {
                    CleanService tableService = new CleanService(logger);
                    String file = commandLine.getOptionValue('c');
                    Map<String, Config> configGroup = tableService.parseConfig(hf, options, file);

                    confirm(configGroup, logger);

                    tableService.clean(configGroup);
                } catch (Exception e) {
                    logger.error("Exception: ", e);
                    System.exit(1);
                }
            }
        } catch (ParseException e) {
            hf.printHelp(AppName, options, true);
            System.exit(1);
        }
    }

    private static void confirm(Map<String, Config> configGroup, Logger logger) {
        StringBuilder cleanInfo = new StringBuilder();
        for (Map.Entry<String, Config> configEntry : configGroup.entrySet()) {
            cleanInfo.append("========== config group[" + configEntry.getKey() + "]  ==========\n");
            Config config = configEntry.getValue();
            cleanInfo.append("dbUrl: ").append(config.getDbUrl()).append("\n");
            cleanInfo.append("mode: ").append(config.getMode()).append("\n");
            cleanInfo.append("tables: ").append(config.getTables()).append("\n");
        }
        cleanInfo.append("confirm clean info? (y/n)");
        String info = cleanInfo.toString();
        logger.info(info);

        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        if (line.equals("n") || line.equals("N")) {
            logger.info("exit.");
            System.exit(1);
        } else if (!line.equals("y") && !line.equals("Y")) {
            confirm(configGroup, logger);
        }
    }

    public static Options createOptions() {
        Options options = new Options();

        Option opt = new Option("h", "help", false, "Print help");
        opt.setRequired(false);
        options.addOption(opt);

        opt = new Option("c", "config", true, "Specify the config file path");
        opt.setRequired(true);
        options.addOption(opt);

        return options;
    }

}
